#ifndef FASYS_FASYS_SUBSCRIBE_CHANNEL_CONTAINER_HPP
#define FASYS_FASYS_SUBSCRIBE_CHANNEL_CONTAINER_HPP

#include "types.hpp"
#include "subscribe_channel.hpp"

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/composite_key.hpp>

namespace fasys{

using namespace boost;
using namespace boost::multi_index;



struct subscribe_channel_ordered_by_subscribe_id_t
  : ordered_unique<
      tag<_subscribe_id_>,
      composite_key<
        subscribe_channel,
        member<subscribe_channel, subscribe_id_t, &subscribe_channel::subscribe_id>,
        member<subscribe_channel, channel_id_t, &subscribe_channel::channel_id>
      >
   >
{
};

struct subscribe_channel_ordered_by_channel_id_t
  : ordered_unique<
      tag<_channel_id_>,
      composite_key<
        subscribe_channel,
        member<subscribe_channel, channel_id_t, &subscribe_channel::channel_id>,
        member<subscribe_channel, subscribe_id_t, &subscribe_channel::subscribe_id>
      >
   >
{
};

struct subscribe_channel_indices
  : indexed_by<
      subscribe_channel_ordered_by_subscribe_id_t,
      subscribe_channel_ordered_by_channel_id_t
    >
{};

typedef multi_index_container<subscribe_channel, subscribe_channel_indices> subscribe_channel_multi_index;


class subscribe_channel_container
  : private subscribe_channel_multi_index
{
  typedef subscribe_channel_multi_index super;
  typedef super::index<_subscribe_id_>::type by_subscribe_id_type;
  typedef super::index<_channel_id_>::type by_channel_id_type;

public:

  void insert(subscribe_id_t subscribe_id, channel_id_t channel_id, subscription* subject)
  {
    super::insert( subscribe_channel(subscribe_id, channel_id, subject) );
  }

  template<typename F>
  void for_each(channel_id_t channel_id, F f) const
  {
    const by_channel_id_type& by_channel_id = super::get<_channel_id_>();
    std::pair<
        by_channel_id_type::const_iterator,
        by_channel_id_type::const_iterator
    > range = by_channel_id.equal_range(channel_id);

    std::for_each(range.first, range.second, f);
  }

};


}
#endif
